package com.gupaoedu.dubbo;

import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.extension.SPI;
import com.alibaba.dubbo.rpc.Protocol;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;
import java.util.regex.Pattern;

/**
 * Hello world!
 */
public class App {

    public static void main11(String[] args){
        SPI defaultAnnotation = Protocol.class.getAnnotation(SPI.class);
        String value = defaultAnnotation.value();
        System.out.println(value);  // "dubbo"

        //正则表达式的意思就是  一个逗号或多个
        Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
        String[] names = NAME_SEPARATOR.split(value);
        System.out.println(names);
        Pattern p = Pattern.compile("\\s*[,]+\\s*");
        String[] strArr = p.split("a,,,,s,b");
        System.out.println(strArr);//结果 数组长度3，[a,s,b]
        /**
         * @Adaptive
         * public class AdaptiveExtensionFactory implements ExtensionFactory {
         *
         * @Adaptive如果是加在类上， 表示当前类是一个自定义的自适应扩展点
         * 如果是加在方法级别上，表示需要动态创建一个自适应扩展点，也就是Protocol$Adaptive
         *
         * @Activate获取类激活注解，即默认的SPI
         * Activate缓存，Activate代表激活的条件
         *
         */
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        ClassPathXmlApplicationContext context = new
                ClassPathXmlApplicationContext
                ("dubbo-client.xml");

//        Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("defineProtocol");
        Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
        /**
         * ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension();
         *
         *  private T injectExtension(T instance) {
         *   ...
         *   // 解析依赖实例的属性名称
         *   // 依赖的实例名称和类型从工厂中获取
         *  }
         *
         *  通过此次对Dubbo SPI的源码初探，知道了Dubbo通过ExtensionLoader实现了一个简单的IOC容器，
         *  通过装饰者模式，实现了类似AOP的功能，从这里面不禁发现，无论在任何软件或者框架的开发中，
         *  都有要把对象的整个生命周期以及生命周期前后的钩子留出来，方便后续扩展，也许是钩子，也许是链式扩展。
         *
         *
         *  Exchanger的接口定义，就是bind和connect ，
         *      bind是服务端调用的，绑定一个端口用来接收客户端的请求。
         *      connect是作为一个客户端去连接服务端，进行和服务端交换。
         *
         *     exchange 信息交换层：封装请求响应模式，同步转异步，
         *          以 Request, Response 为中心，
         *          扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
         *
         */
        System.out.println(protocol.getDefaultPort());

        //得到 IGpHello 的远程代理对象
        IGpHello iGpHello = (IGpHello) context.getBean("gpHelloService");
        System.out.println(iGpHello.sayHello("Mic"));

//        IDemoService iDemoService = (IDemoService) context.getBean("demoService");
//        System.out.println(iDemoService.protocolDemo("Mic"));

        System.in.read(); //阻塞当前进程
    }

}
